package cn.windstudio;

import java.util.Random;
import java.util.Vector;

import cn.windstudio.Map.MyPanel;

public class SnakeManager implements Runnable {

	private static final SnakeManager sManager = new SnakeManager();
	public static final int UP = 1, RIGHT = 2, DOWN = -1, LEFT = -2;

	private int POINT = SnakeManager.RIGHT;
	private boolean GAMEOVER = false;
	private int SPEED = 500;
	private int nodeSize = 40;
	private Vector<snakeNode> vt = new Vector<>();
	private snakeNode snakeHead = new snakeNode();
	private Coordinate foodXY = new Coordinate();
	private Coordinate nextPoint;
	private MyPanel myPanel;

	private SnakeManager() {
		this.init();
	}

	private void init() {
		snakeHead.getXY().X = new Random().nextInt(Map.mapSize.X - nodeSize * 3 + 1);
		snakeHead.getXY().X = snakeHead.getXY().X - (snakeHead.getXY().X % nodeSize);
		snakeHead.getXY().Y = new Random().nextInt(Map.mapSize.Y - nodeSize * 3 + 1);
		snakeHead.getXY().Y = snakeHead.getXY().Y - (snakeHead.getXY().Y % nodeSize);
		nextPoint = new Coordinate(snakeHead.getXY());
		vt.add(snakeHead);
		do {
			foodXY.X = new Random().nextInt(Map.mapSize.X + 1);
			foodXY.X = foodXY.X - (foodXY.X % nodeSize);
			foodXY.Y = new Random().nextInt(Map.mapSize.Y + 1);
			foodXY.Y = foodXY.Y - (foodXY.Y % nodeSize);
		} while (foodXY.equal(snakeHead.getXY()));
		this.newNode();
	}

	public Coordinate getFoodXY() {
		return foodXY;
	}

	public void getMyPanel(MyPanel myPanel) {
		this.myPanel = myPanel;
	}

	public void setPOINT(int pOINT) {
		if (pOINT * pOINT != POINT * POINT)
			POINT = pOINT;
	}

	public boolean isGAMEOVER() {
		return GAMEOVER;
	}

	public Vector<snakeNode> getVt() {
		return vt;
	}

	public void newNode() {
		vt.add(new snakeNode(new Coordinate(-1, -1)));
	}

	private boolean judge(Coordinate xy) {
		for (int i = vt.size() - 1; i >= 0; i--) {
			if (vt.get(i).getXY().equal(xy))
				return true;
		}
		return false;
	}

	public void newFood() {
		do {
			foodXY.X = new Random().nextInt(Map.mapSize.X-39);
			foodXY.X = foodXY.X - (foodXY.X % nodeSize);
			foodXY.Y = new Random().nextInt(Map.mapSize.Y-39);
			foodXY.Y = foodXY.Y - (foodXY.Y % nodeSize);
		} while (judge(foodXY));
	}

	public void run() {
		while (!GAMEOVER) {
			switch (POINT) {
			case SnakeManager.UP:
				nextPoint.Y = nextPoint.Y - nodeSize;
				break;
			case SnakeManager.RIGHT:
				nextPoint.X = nextPoint.X + nodeSize;
				break;
			case SnakeManager.DOWN:
				nextPoint.Y = nextPoint.Y + nodeSize;
				break;
			case SnakeManager.LEFT:
				nextPoint.X = nextPoint.X - nodeSize;
				break;
			}

			if (nextPoint.X < 0 || nextPoint.X >= Map.mapSize.X || nextPoint.Y < 0
					|| nextPoint.Y >= Map.mapSize.Y || judge(nextPoint)) {
				GAMEOVER = true;
			}
			
			for (int i = vt.size() - 1; i > 0; i--) {
				vt.get(i).setXY(vt.get(i - 1).getXY());
			}
			vt.get(0).setXY(nextPoint);
			myPanel.repaint();

			if (vt.get(0).getXY().equal(foodXY)) {
				newFood();
				newNode();
			}

			try {
				Thread.sleep(SPEED);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

		}
	}

	public static SnakeManager getManager() {
		return sManager;
	}
}
